package edu.pdx.LAMA.AndroidCourse.scheduler;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import edu.pdx.LAMA.AndroidCourse.ModelLayer.EventDetails;
import edu.pdx.LAMA.AndroidCourse.ModelLayer.EventService;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class EventDetailsFragment extends Fragment implements LocationListener{
	
	private static final String TAG = "EventDetailsFragment";
	
	private ArrayList<EventDetails> details;
	private ArrayList<EventDetails> dailyEvents;
	private Context context;
	
	AlertDialog.Builder builder;
	
	// Location Related
	protected LocationListener locationListener;
	protected LocationManager locationManager;
	protected double latitude,longitude;
	
	private EventDetails eventDetails;
	private TextView title;
	private TextView startTime;
	private TextView endTime;
	private TextView priority;
	private TextView location;
	private TextView category;
	private TextView alarmTime;
	private Button travelTimeButton;
	private Button editButton;
	private TextView dailyEventText;
	private Button deleteButton;
	
	private String selectedDate;
	
	private String finalSummary;
	private String finalDuration;
	
	public static final String EXTRA_EVENT_SELECTED = "edu.pdx.LAMA.AndroidCourse.scheduler.eventSelected";
	public static final String EXTRA_EVENT_DATE_SELECTED = "edu.pdx.LAMA.AndroidCourse.scheduler.eventDateSelected";
	public static final String EXTRA_ALL_EVENTS_FOR_DAY = "edu.pdx.LAMA.AndroidCourse.scheduler.allEventsForDay";
	public static final String EXTRA_MY_INT = "edu.pdx.LAMA.AndroidCourse.scheduler.index";
	public static final String EXTRA_MY_STRING = "edu.pdx.LAMA.AndroidCourse.scheduler.date";
	
	public EventDetailsFragment(){
		this.context = getActivity();
	}
	
	/*public EventDetailsFragment(Context context) {
		// TODO Auto-generated constructor stub
		this.context = context;
	}*/
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
		try{
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
		} catch(Exception e){
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
		}
		EventService eventService = new EventService(getActivity());
		//details = eventService.getDailyEvent();
		
		
		
		int id = getArguments().getInt(EXTRA_MY_INT);
		selectedDate = getArguments().getString(EXTRA_MY_STRING);
		
		details = (ArrayList<EventDetails>) eventService.getDailyEvents();
		ArrayList<EventDetails> temp = (ArrayList<EventDetails>) eventService.getDatewiseEvents(selectedDate);
		Iterator<EventDetails> it = temp.iterator();
		while(it.hasNext()){
			details.add(it.next());
		}
		//details = (ArrayList<EventDetails>) eventService.getDatewiseEvents(selectedDate);
		
		//details = (ArrayList<EventDetails>) getArguments().getSerializable(EXTRA_ALL_EVENTS_FOR_DAY);
		//int id = getActivity().getIntent().getIntExtra(EXTRA_EVENT_SELECTED, 1);
		//details = (ArrayList) getActivity().getIntent().getSerializableExtra(EXTRA_ALL_EVENTS_FOR_DAY);
		Log.d(TAG, "id "+id);
		if(details.size()==0){
			Log.d(TAG, "The array is empty");
		}
		
		eventDetails = details.get(id);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		//return super.onCreateView(inflater, container, savedInstanceState);
		View v = inflater.inflate(R.layout.fragment_event_details, container, false);
		
		title = (TextView) v.findViewById(R.id.title_event_static_display);
		title.setText(eventDetails.getTitle());
		
		startTime = (TextView) v.findViewById(R.id.start_time_event_static_display);
		//int startTime = eventDetails.getStartTime();
		startTime.setText(eventDetails.getStartTime());
		
		endTime = (TextView) v.findViewById(R.id.end_time_event_static_display);
		endTime.setText(eventDetails.getEndTime());
		
		priority = (TextView) v.findViewById(R.id.priority_event_static_display);
		priority.setText(eventDetails.getPriority());
		
		location = (TextView) v.findViewById(R.id.location_event_static_display);
		location.setText(eventDetails.getLocation());
		
		category = (TextView) v.findViewById(R.id.category_event_static_display);
		category.setText(eventDetails.getCategory());
		
		alarmTime = (TextView) v.findViewById(R.id.alarm_event_static_display);
		alarmTime.setText(((Integer)eventDetails.getAlarmTime()).toString());
		
		dailyEventText = (TextView) v.findViewById(R.id.dailyEventTextBox);
		if (eventDetails.isDailyEvent()){
			dailyEventText.setText("This is a Daily Event");
		}
		
		editButton = (Button) v.findViewById(R.id.edit_button);
		
		// Here the button would be used to create a dialog fragment
		// that dialog will as of now display the current location
		travelTimeButton = (Button) v.findViewById(R.id.getTravelTime);
		travelTimeButton.setText("Calculate Travel Time From Current Location");
		travelTimeButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (eventDetails.getLocation() == null || eventDetails.getLocation().equalsIgnoreCase("")){
					Toast.makeText(getActivity(), "You haven't entered a location, Can't calculate the travel time", Toast.LENGTH_SHORT).show();
				}
				else{
					String dummyLoc = eventDetails.getLocation().replace(" ", "+");
					
					String serverURL = "https://maps.googleapis.com/maps/api/directions/json?origin="+latitude+","+longitude+"&destination="+dummyLoc+"&key=AIzaSyCRyHYwg0_IlFTil7o9wCvVBWiEA5CEJfY";
					new CalcTravelTimeClass().execute(serverURL);
					//showDialogBox();
				}
			}
		});
		// this will have to change
		//editButton.setEnabled(false);
		editButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent i = new Intent(getActivity(), CreateOrModifyEventActivity.class);
				i.putExtra(CreateOrModifyEventActivity.EXTRA_EVENT_ID, eventDetails.getID());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_EVENT_DATE, eventDetails.getDate());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_TITLE, eventDetails.getTitle());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_START_TIME, eventDetails.getStartTime());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_END_TIME, eventDetails.getEndTime());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_PRIORITY, eventDetails.getPriority());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_LOCATION, eventDetails.getLocation());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_CATEGORY, eventDetails.getCategory());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_ALARM, eventDetails.getAlarmTime());
				i.putExtra(CreateOrModifyEventActivity.EXTRA_DAILYEVENT, eventDetails.isDailyEvent());
				
				startActivity(i);
			}
		});
		
		deleteButton = (Button) v.findViewById(R.id.deleteButton);
		deleteButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				try{
					EventService eventService = new EventService(getActivity());
					if (eventDetails.getID()<999999){
						eventService.deleteEvent(eventDetails.getID());
					} else {
						eventService.deleteDailyEvent(eventDetails.getID());
					}
					// this line here can be dangerous
					//getActivity().finish();
					Intent ix = new Intent(getActivity(), ScheduleActivity.class);
					startActivity(ix);
				} catch (Exception e){
					Toast.makeText(getActivity(), "An error occured while deleting the event", Toast.LENGTH_SHORT).show();
				}
				
			}
		});
		
		return v;
	}
	
	public static EventDetailsFragment newInstance(int index, String date, Context inContext){
		Log.d(TAG, "The value of index in the fragment is "+index);
		Bundle args = new Bundle();
		args.putInt(EXTRA_MY_INT, index);
		args.putString(EXTRA_MY_STRING, date);
		//args.putSerializable(EXTRA_ALL_EVENTS_FOR_DAY, eventD);
		
		//EventDetailsFragment detailsFragment = new EventDetailsFragment(inContext);
		EventDetailsFragment detailsFragment = new EventDetailsFragment();
		detailsFragment.setArguments(args);
		
		return detailsFragment;
	}
	
	private void showDialogBox() {
		// TODO Auto-generated method stub
		
		
		//
		builder = new AlertDialog.Builder(getActivity());
		builder.setTitle("Estimated Travel Time");
		if ((latitude==0.0 && longitude == 0.0) || finalDuration==null || finalSummary == null){
			builder.setMessage("Location currently unavailable, please try again in sometime");
		}
		else{
			builder.setMessage("Estimated Duration: "+finalDuration+"\n"+"Suggested Route: via "+finalSummary);
		}
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.cancel();
			}
		});
		builder.show();
	}

	@Override
	public void onLocationChanged(Location location) {
		// TODO Auto-generated method stub
		Log.d(TAG, "is it going in here?");
		latitude = location.getLatitude();
		longitude = location.getLongitude();
		//builder.setMessage("Lat: "+location.getLatitude()+" Lon: "+location.getLongitude());
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub
		
	}
	
	private class CalcTravelTimeClass extends AsyncTask<String, Void, Void> {

		private String content;
		private String error = null;
		// it is getting the following context from the pager activity
		private ProgressDialog dialog = new ProgressDialog(getActivity());
		String data ="";
		
		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			dialog.setMessage("Please Wait...");
			dialog.show();
		}
		
		@Override
		protected Void doInBackground(String... urls) {
			// TODO Auto-generated method stub
			//return null;
			BufferedReader bufferedReader=null;
			try{
				URL url = new URL(urls[0]);
				URLConnection conn = url.openConnection();
				conn.setDoOutput(true);
				OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
				wr.write(data);
				wr.flush();
				
				bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				StringBuilder sb = new StringBuilder();
				String line=null;
				
				while((line = bufferedReader.readLine())!=null){
					sb.append(line);
				}
				
				content = sb.toString();
			} catch(Exception e){
				error = e.getMessage();
			} finally {
				try{
					bufferedReader.close();
				} catch (Exception e){
					// Do nothing as of now because this shouldn't throw an error
				}
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			String duration = null;
			String summary = "";
			dialog.dismiss();
			if(error!=null){
				Log.d(TAG, error);
			} else {
				JSONObject jsonResponse;
				try{
					jsonResponse = new JSONObject(content);
					JSONArray jsonMainNode = jsonResponse.optJSONArray("routes");
					//  god knows whats going on here
					JSONObject routesChildNode = jsonMainNode.getJSONObject(0);
					summary = routesChildNode.optString("summary");
					JSONArray legsArray = routesChildNode.getJSONArray("legs");
					JSONObject leg = legsArray.getJSONObject(0);
					JSONObject durationObject = leg.getJSONObject("duration");
					duration = durationObject.getString("text");
					
					//JSONArray durationChildNode = jsonMainNode.optJSONArray("legs");
					//summary = summaryChildNode.optString("summary");
					//duration = durationChildNode.optString("duration");
					/*int lengthJSONArr = jsonMainNode.length();
					for (int i=0;i<lengthJSONArr;i++){
						JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
						summary = jsonChildNode.optString("summary");
						legs = jsonChildNode.optString("legs");
						duration = jsonChildNode.optString("duration");
					}*/
					
					finalDuration = duration;
					finalSummary = summary;
					
					showDialogBox();
					Log.d(TAG, "Duration: "+duration+" Summary: "+summary);
				} catch (Exception e){
					Log.d(TAG, "JSON Parsing Exception");
				}
			}
			
			//Log.d(TAG, content);
		}
		
	}
}
